package com.github.pig.admin.controller.app;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.github.pig.admin.common.constants.AttendanceConstant;
import com.github.pig.admin.model.attendance.*;
import com.github.pig.admin.service.attendance.*;
import com.github.pig.admin.util.AjaxJson;
import com.github.pig.common.constant.CommonConstant;
import com.github.pig.common.util.CalulateTwoLanLon;
import com.github.pig.common.util.DateTools;
import com.github.pig.common.web.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author wf_sxf@163.com
 * @date 2018-11-22 15:45
 */
@RestController
@Slf4j
@RequestMapping("/api/attendance/")
public class AttendanceApi extends BaseController {

    @Autowired
    private IAttendanceRecordService recordService;
    @Autowired
    private IAttendanceGroupUserService groupUserService;
    @Autowired
    private IAttendanceAddrService addrService;
    @Autowired
    private IAttendanceWifiService wifiService;
    @Autowired
    private IAttendanceTimesService timesService;


    /**
     * 查询打卡记录 按日
     */
    @GetMapping("listAttendForDay")
    public AjaxJson listAttendForDay(@RequestParam("date") String date) {
        AjaxJson json = new AjaxJson();
        json.setSuccess(true);
        try {
            String username = getUserName();
            if (StringUtils.isBlank(username)) {
                json.setMsg("未登录");
                json.setSuccess(false);
                return json;
            }
            //根据日期查询当天考勤记录
            json.setObj(recordService.getByUserForDay(username,date));
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询打卡记录失败", e);
            json.setSuccess(false);
            json.setMsg("查询打卡记录失败：" + e.getMessage());
        }
        return json;
    }

    /**
     * 查询打卡记录  按月
     */
    @GetMapping("listAttendForMonth")
    public AjaxJson listAttendForMonth(@RequestParam("date") String date) {
        AjaxJson json = new AjaxJson();
        json.setSuccess(true);
        Map<String, Object> result = new HashMap<>();

        try {
            String username = getUserName();
            if (StringUtils.isBlank(username)) {
                json.setMsg("未登录");
                json.setSuccess(false);
                return json;
            }
            List<AttendanceRecord> records = recordService.getByUserForMonth(username,date );
            //迟到.map(AttendanceRecord::getIsNormal)
            Map<String, List<AttendanceRecord>> maps = records.stream().collect(Collectors.groupingBy(AttendanceRecord::getIsNormal));
            result.put("late", maps.get(AttendanceRecord.IS_NORMAL_LATE));
            result.put("leave", maps.get(AttendanceRecord.IS_NORMAL_LEAVE));
            List<String> rest = DateTools.getWeekendInMonth(date);
            result.put("rest", rest);
            Map<String, List<AttendanceRecord>> atteds = records.stream().collect(Collectors.groupingBy(AttendanceRecord::getDate));
            List<String> attends = new ArrayList<>(atteds.keySet());
            result.put("attend",attends);
            Set<String> missing = new HashSet<>();
            //获取缺卡日期
            result.put("missing",DateTools.getMissingDay(attends,DateTools.getDaysOfMonth(date)));;
            json.setObj(result);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询打卡记录失败", e);
            json.setSuccess(false);
            json.setMsg("查询打卡记录失败：" + e.getMessage());
        }
        return json;
    }

    /**
     * 获取考勤类型
     */
    @GetMapping("attendanceType")
    public AjaxJson attendanceType() {
        AjaxJson json = new AjaxJson();
        json.setSuccess(true);
        try {
            String username = getUserName();
            if (StringUtils.isBlank(username)) {
                json.setMsg("未登录");
                json.setSuccess(false);
                return json;
            }
            //查询用户考勤组
            AttendanceGroup group = groupUserService.getByUserName(username);
            if (group == null) {
                json.setSuccess(false);
                json.setMsg("考勤组为空，请联系管理员添加考勤组。");
                return json;
            }
            json.setObj(group);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("获取考勤类型异常，", e);
            json.setSuccess(false);
            json.setMsg("获取考勤类型异常:" + e.getMessage());
            return json;
        }
        return json;
    }

    /**
     * 是否在考勤范围内  固定地点
     * ,@RequestParam("IMEI") String imei
     */
    @GetMapping("inRange_addr")
    public AjaxJson inRange(@RequestParam(value = "groupId", required = true) String groupId, @RequestParam("longitude") Double longitude, @RequestParam("latitude") Double latitude) {
        AjaxJson json = new AjaxJson();
        json.setSuccess(true);
        try {
            Map<String, Object> result = new HashMap();
            Map<String, Object> recently = new HashMap();
            //判断考勤范围
            result.put("type", "address");
            Wrapper wrapper = new EntityWrapper();
            wrapper.eq(CommonConstant.DEL_FLAG, CommonConstant.STATUS_NORMAL);
            wrapper.eq("group_id", groupId);
            List<AttendanceAddr> list = addrService.selectList(wrapper);

            if (list != null && list.size() > 0) {
                //计算考勤距离
                for (AttendanceAddr addr : list) {
                    if (addr.getLatitude() != null && addr.getLongitude() != null && addr.getRange() != null) {
                        double distance = CalulateTwoLanLon.getDistance(addr.getLatitude(), addr.getLongitude(), latitude, longitude);

                        if (distance <= addr.getRange()) {
                            result.put("inRange", true);
                            result.put("data", addr);
                            result.put("distance", 0);
                            json.setObj(result);
                            return json;
                        }
                        //获取最近的考勤点
                        if (recently.get("data") != null && recently.get("distance") != null && (double) recently.get("distance") > distance) {
                            //最近的考勤点
                            recently.put("data", addr);
                            //最近距离
                            recently.put("distance", distance);
                        }
                    }
                }
                result.put("inRange", false);
                result.putAll(recently);
                json.setSuccess(true);
                json.setObj(result);
                return json;
            } else {
                json.setSuccess(false);
                json.setMsg("考勤地点为空，请联系管理员添加考勤地点。");
                return json;
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("获取勤范围异常，", e);
            json.setSuccess(false);
            json.setMsg("获取勤范围异常:" + e.getMessage());
        }
        return json;
    }

    /**
     * 是否是考勤WIFI
     */
    @GetMapping("inRange_wifi")
    public AjaxJson inRange_wifi(@RequestParam(value = "groupId", required = true) String groupId, @RequestParam("mac") String mac) {
        AjaxJson json = new AjaxJson();
        json.setSuccess(true);
        try {
            Map<String, Object> result = new HashMap();
            result.put("type", "wifi");

            Wrapper wrapper = new EntityWrapper();
            wrapper.eq(CommonConstant.DEL_FLAG, CommonConstant.STATUS_NORMAL);
            wrapper.eq("group_id", groupId);
            List<AttendanceWifi> list = wifiService.selectList(wrapper);

            if (list != null && list.size() > 0) {
                //计算考勤距离
                for (AttendanceWifi wifi : list) {
                    if (mac.equals(wifi.getMac())) {
                        result.put("inRange", true);
                        result.put("data", wifi);
                        json.setObj(result);
                    }
                }
                result.put("inRange", false);
                json.setObj(result);
                return json;
            } else {
                json.setSuccess(false);
                json.setMsg("考勤WIFI为空，请联系管理员添加考勤地点。");
                return json;
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("获取勤范围异常，", e);
            json.setSuccess(false);
            json.setMsg("获取勤范围异常:" + e.getMessage());
        }
        return json;
    }

    /**
     * 打卡上班
     */
    @PostMapping("punched")
    public AjaxJson punched(@RequestBody AttendanceRecord record) {
        AjaxJson json = new AjaxJson();
        json.setSuccess(true);
        try {
            String username = getUserName();
            if (StringUtils.isBlank(username)) {
                json.setMsg("未登录");
                json.setSuccess(false);
                return json;
            }
            String time = DateTools.getCurrentSysData(DateTools.DEFAULT_FORMAT);
            //查询当天考勤手机是否重复
            boolean flag = timesService.judgeEquipment(time, record.getImei(), username);
            if (!flag) {
                json.setMsg("今日有多账号使用此手机打卡，暂不提供打卡功能，有疑问请联系管理员。");
                json.setSuccess(false);
                return json;

            }
            //时刻表
            AttendanceTimes times = timesService.getByTime(time, username);
            if (times == null) {
                times = new AttendanceTimes();
                times.setAttendanceTime(time);
                times.setUserName(username);
                times.setRecordType(AttendanceConstant.RECORD_TYPE_ING);
                times.setTimes(1);
            }
            //当前打卡是否有异常
            if (!AttendanceConstant.RECORD_TYPE_NORMAL.equals(record.getIsNormal())) {
                //有异常
                times.setRecordType(record.getIsNormal());

            }
            //插入打卡数据，更改times表状态


        } catch (Exception e) {

        }
        return json;
    }


}
